﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Terminal.Advanced_AEUC_settings_controls.Settings_AUX;

namespace Terminal.Advanced_AEUC_settings_controls.Scripting
{
    /// <summary>
    /// Script action base class
    /// </summary>
    class ScrBasicAction
    {
        /// <summary>
        /// Should script execution halt upon this action
        /// </summary>
        protected bool breakPoint = false;
        /// <summary>
        /// Action display text
        /// </summary>
        protected string dispName;
        /// <summary>
        /// Usage help and comments text for the action
        /// </summary>
        protected string usageHelp;
        /// <summary>
        /// Semaphore to wait for user input when break point is reached
        /// </summary>
        Semaphore waitUIStep;

        /// <summary>
        /// Deleate for no parameter no return events.
        /// </summary>
        public delegate void noParamnoReturn();
        /// <summary>
        /// Event fired when a break point action is reached.
        /// </summary>
        public event noParamnoReturn OnBreakPointReached;

        /// <summary>
        /// Public constructor for the script action
        /// </summary>
        /// <param name="iDispName">Action display text</param>
        /// <param name="iUsageHelp">Usage help and comments text for the action</param>
        public ScrBasicAction(string iDispName, string iUsageHelp)
        {
            dispName = iDispName;
            usageHelp = iDispName + " " + iUsageHelp + "\n";
            waitUIStep = new Semaphore(0, 1);
        }

        /// <summary>
        /// Blocks waiting for user input while firing off related event.
        /// </summary>
        protected void WaitUserInput()
        {
            if (OnBreakPointReached != null)
                OnBreakPointReached();

            waitUIStep.WaitOne();
        }

        /// <summary>
        /// When user input is ready realease the thread.
        /// </summary>
        public void Go()
        {
            waitUIStep.Release();
        }

        /// <summary>
        /// Perform the action using specified parameters.
        /// </summary>
        /// <param name="paramList">List of the input/output parameters for the action</param>
        /// <returns>True if action is succesful</returns>
        public virtual bool Do(List<object> paramList)
        {
            if (breakPoint)
                WaitUserInput();

            return true;
        }

        /// <summary>
        /// Returns a List containing objects of the parameter list required for the Do function.
        /// </summary>
        /// <returns>List of parameter objects</returns>
        public virtual List<Type> GetParamList()
        {
            return null;
        }

        /// <summary>
        /// Generate C source code for specified parameters
        /// </summary>
        /// <param name="paramlist">List of input/output parameters for the action</param>
        /// <returns>C source string</returns>
        public virtual string GenerateSourceCode(List<object> paramList)
        {
            return "Source code generation not available for this command.";
        }

        /// <summary>
        /// Returns a List containing objects of the parameter list required for the GenerateSourceCode function.
        /// </summary>
        /// <returns>List of parameter objects</returns>
        public virtual List<Type> GetParamListSourceGen()
        {
            return null;
        }

        /// <summary>
        /// Should script execution halt upon this action
        /// </summary>
        public bool SetBreakPoint
        {
            get
            {
                return breakPoint;
            }
            set
            {
                breakPoint = value;
            }
        }
        /// <summary>
        /// Action display text
        /// </summary>
        public string DisplayName
        {
            get
            {
                return dispName;
            }
            set
            {
                dispName = value;
            }
        }
        /// <summary>
        /// Usage help and comments text for the action
        /// </summary>
        public string UsageSummary
        {
            get
            {
                return usageHelp;
            }
            set
            {
                usageHelp = value;
            }
        }
        /// <summary>
        /// Overrided ToString() method
        /// </summary>
        /// <returns>Command display name</returns>
        public override string ToString()
        {
            return DisplayName;
        }
    }
}
